/*
 * @Author: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
 * @Date: 2025-03-17 15:47:14
 * @LastEditors: error: error: git config user.name & please set dead value or install git && error: git config user.email & please set dead value or install git & please set dead value or install git
 * @LastEditTime: 2025-03-17 17:25:50
 * @FilePath: /boost_searcher/searcher.hpp
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#include "index.hpp"
#include <algorithm>
#include <jsoncpp/json/json.h>
namespace ns_searcher
{
    class Searcher
    {
    public:
        Searcher()
        {
        }
        ~Searcher()
        {
        }

    public:
        void InitSearcher(const std::string &input)
        {
            // 1. 获取或者创建index对象
            index = ns_index::Index::GetInstance();
            // 2. 根据index对象建⽴索引
            index->BuildIndex(input);
        }
        // query: 搜索关键字
        // json_string: 返回给用户浏览器的搜索结果
        void Search(const std::string &query, std::string *json_string)
        {
             //1.[分词]:对我们的query进⾏按照searcher的要求进⾏分词
             std::vector<std::string> words;
             ns_util::JiebaUtil::CutString(query,&words);
             //2.[触发]:就是根据分词的各个"词"，进⾏index查找
             ns_index::InvertedList inverted_list_all;//内部InvertedElem
             for(auto word:words)
             {
                boost::to_lower(word);
                ns_index::InvertedList* inverted_list = index->GetInvertedList(word);
                if(inverted_list == nullptr)
                {
                    continue;
                }
                //将查找结果汇总
                inverted_list_all.insert(inverted_list_all.end(),inverted_list->begin(),inverted_list->end());
             }
             //3.[合并排序]：汇总查找结果，按照相关性(weight)降序排序
             std::sort(inverted_list_all.begin(),inverted_list_all.end(),[](const ns_index::InvertedElem& e1,const ns_index::InvertedElem& e2)
             {
                 return e1.weight > e2.weight;
             });
             //4.[构建]:根据查找出来的结果，构建json串  -- jsoncpp --通过jsoncpp完成序列化&&反序列化
             Json::Value root;
             for(auto& item : inverted_list_all)
             {
                //根据doc_id获取到doc_info
                ns_index::DocInfo* doc = index->GetforwardIndex(item.doc_id);
                if(doc == nullptr)
                {
                    continue;
                }
                Json::Value elem;
                elem["title"] = doc->title;
                elem["desc"] = doc->content;//content是文档的去标签的结果，但是不是我们想要的，我们要的是一部分 TODO
                elem["url"] = doc->url;
                root.append(elem);
             }
            Json::StyledWriter writer;
            *json_string = writer.write(root);
        }

    private:
        ns_index::Index *index;
    };

}